Editing Custom Types
The sample object has two properties, HomePhone and WorkPhone, of type PhoneNumber. The PropertyGrid control doesn’t have any built-in understanding of the PhoneNumber type, so it displays these values using their ToString() method, and allows the user to drill into them and edit their CountryCode, RegionCode and Number properties individually.
We would like to teach the PropertyGrid control a more useful way of displaying the PhoneNumber type, so that the user can see the phone number more readily and edit it more easily. To do this, we will create a type editor and attach it to the grid.
Defining the Editing Template
A type editor is basically a data template with data bindings appropriate for the edited type. The editor template for the PhoneNumber type can be pretty simple: three TextBoxes, one bound to the CountryCode property, one to the RegionCode property and one to the Number property. We will also provide some read-only TextBlocks to give the user a visual cue as to the demarcation between the boxes. So the editor data template looks like this:
<DataTemplate x:Key='PhoneNumberEditor'> <StackPanel Orientation='Horizontal'> <StackPanel.Resources> <Style TargetType='{x:Type TextBlock}'> <Setter Property='Foreground' Value='{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}'/> <Setter Property='FontWeight' Value='Bold'/> </Style> <Style TargetType='{x:Type ms:TextBox}'> <Setter Property='BorderThickness' Value='0'/> </Style> </StackPanel.Resources> <TextBlock>+</TextBlock> <ms:TextBox Text='{Binding Path=CountryCode, UpdateSourceTrigger=PropertyChanged}'/> <TextBlock> (</TextBlock> <ms:TextBox Text='{Binding Path=RegionCode, UpdateSourceTrigger=PropertyChanged}'/> <TextBlock>) </TextBlock> <ms:TextBox Text='{Binding Path=Number, UpdateSourceTrigger=PropertyChanged}'/> </StackPanel> </DataTemplate>
Telling the Property Grid to Use the New Template
We now need to tell the PropertyGrid control to use this template for PhoneNumber objects. To do this, add a TypeEditor object to the PropertyGrid.Editors collection. You can do this using XAML property syntax as follows:
<ms:PropertyGrid.Editors> <ms:TypeEditor EditedType='{x:Type t:PhoneNumber}' EditorTemplate='{StaticResource PhoneNumberEditor}'/> </ms:PropertyGrid.Editors>
Notice that, wherever a PhoneNumber property appears in the grid, the new editor is used to edit it.
Combining Custom Editors With Expanding Nodes
By default, if you provide an editor for a type, the property grid will stop showing that type as expandable – users won’t be able to edit individual properties. Sometimes that’s undesirable:
- If the type has lots of properties, most of which are rarely used, you might design an in-place editor to edit the common properties, but the user would still need to be able to get at the other properties somehow.
- If you don’t want to provide in-place editing, but you want to present something more meaningful than the ToString() representation, you can create a read-only data template and associate this with the type. (There’s an example of this in the Templating sample.) In this case the user needs to be able to expand the node to perform the actual editing.
To tell the PropertyGrid to allow users to expand a node even though there is an editor provided, set the AllowExpand property (or XAML attribute) of the editor to True.
See 03_EditingCustomTypes.xaml in the PropertyGridCustomization project.
Next step: Providing a Custom Editor for a Property.